--wuqibo
--2021.7.28
--拖动翻页封装，用一个页面复用，滑出画外的瞬间触发内容切换并从另外一边滑入，模拟无限翻页效果，并在画面居中停止，不像ScollRect停在任何位置
--[[
    使用方法(最后一个参数可选，不传则不自动翻页):
    self.pageDragger = PageDragger:new(self.pageTrans, 450, 3, function(index)
        Log(index, "切换到这个索引的内容")
    end, 5)
    self.pageDragger:Destroy()
]]
Screen = UnityEngine.Screen
Input = UnityEngine.Input
Time = UnityEngine.Time

local PageDragger = fb_class("PageDragger")

function PageDragger:ctor(pageTransform, maskWidth, pageCount, onChange, autoInterval)
    self.page = pageTransform
    self.maskWidth = maskWidth
    self.pageCount = pageCount
    self.onChange = onChange
    self.autoInterval = autoInterval
    self.autoTimer = self.autoInterval and Time.time + self.autoInterval or 0
    self.currIndex = 1
    self.canPress = true
    self.moveState = 0
    self.updateHandler = UpdateBeat:CreateListener(self.Update, self)
    UpdateBeat:AddListener(self.updateHandler)
    UIEventListener.Get(pageTransform).onPointerDown =
        UIEventListener.PointerEventDelegate(
        function()
            self:OnPress()
        end
    )
end

---@private
function PageDragger:ScreenPosToUIPos(pos)
    if not self.uiSize then
        self.uiSize = {}
        self.uiSize.y = 1080
        self.uiSize.x = self.uiSize.y * Screen.width / Screen.height
    end
    pos.x = self.uiSize.x * (pos.x - Screen.width * 0.5) / Screen.width
    pos.y = self.uiSize.y * (pos.y - Screen.height * 0.5) / Screen.height
    return pos
end

---@private
function PageDragger:OnPress()
    if self.canPress then
        self.canPress = false
        self.prePos = self:ScreenPosToUIPos(Input.mousePosition)
        self.pressPos = self.prePos
        self.canDrag = true
    end
end

---@private
function PageDragger:Update()
    if self.canDrag then
        local touchPos = self:ScreenPosToUIPos(Input.mousePosition)
        local delta = touchPos.x - self.prePos.x
        self.prePos = touchPos
        local pos = self.page.localPosition
        pos.x = pos.x + delta
        self.page.localPosition = pos

        if Input.GetMouseButtonUp(0) then
            self.canDrag = false

            if touchPos.x - self.pressPos.x > 100 then
                self:Previous()
            elseif self.pressPos.x - touchPos.x > 100 then
                self:Next()
            else
                self:BackToCenter()
            end
        end
    end

    --自动翻页
    if self.autoInterval and self.pageCount > 1 then
        if self.autoTimer < Time.time then
            self.autoTimer = Time.time + self.autoInterval
            if self.currIndex >= self.pageCount then
                self.currIndex = 0
            end
            self:Next()
        end
    end
end

---@private
function PageDragger:BackToCenter()
    self.page:DOLocalMoveX(0, 0.3):SetEase(Ease.OutSine):OnComplete(
        function()
            self.canPress = true
        end
    )
end

--对外公共方法----------------------------------------------------------------------------------------------

--设置当前停留在第几页
---@public
function PageDragger:InitPage(pageIndex)
    self.currIndex = pageIndex
    if self.onChange then
        self.onChange(self.currIndex)
    end
end

--滑到前一页
---@public
function PageDragger:Previous()
    if self.currIndex <= 1 or self.pageCount == 1 then
        self:BackToCenter()
        return
    end
    self.page:DOLocalMoveX(self.maskWidth, 0.1):SetEase(Ease.Linear):OnComplete(
        function()
            if self.currIndex == nil then
                return
            end
            self.currIndex = self.currIndex - 1
            if self.currIndex < 1 then
                self.currIndex = 1
            end
            if self.onChange then
                self.onChange(self.currIndex)
            end
            local pos = self.page.localPosition
            pos.x = -self.maskWidth
            self.page.localPosition = pos
            self.page:DOLocalMoveX(10, 0.3):SetEase(Ease.OutSine):OnComplete(
                function()
                    if IsNil(self.page) then
                        return
                    end
                    self.page:DOLocalMoveX(0, 0.1):SetEase(Ease.OutSine):OnComplete(
                        function()
                            self.canPress = true
                        end
                    )
                end
            )
        end
    )
end

--滑到下一页
---@public
function PageDragger:Next()
    if self.currIndex >= self.pageCount or self.pageCount == 1 then
        self:BackToCenter()
        return
    end
    self.page:DOLocalMoveX(-self.maskWidth, 0.1):SetEase(Ease.Linear):OnComplete(
        function()
            if self.currIndex == nil then
                return
            end
            self.currIndex = self.currIndex + 1
            if self.currIndex > self.pageCount then
                self.currIndex = self.pageCount
            end
            if self.onChange then
                self.onChange(self.currIndex)
            end
            local pos = self.page.localPosition
            pos.x = self.maskWidth
            self.page.localPosition = pos
            self.page:DOLocalMoveX(-10, 0.3):SetEase(Ease.OutSine):OnComplete(
                function()
                    if IsNil(self.page) then
                        return
                    end
                    self.page:DOLocalMoveX(0, 0.1):SetEase(Ease.OutSine):OnComplete(
                        function()
                            self.canPress = true
                        end
                    )
                end
            )
        end
    )
end

--父级UI销毁时，同时执行该方法
---@public
function PageDragger:Destroy()
    UpdateBeat:RemoveListener(self.updateHandler)
    fb_clear(self)
end

return PageDragger
